package jf.jextn.io;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

import jf.jextn.JExtn;

public class ResourceUtil extends IOUtil {
    public static final String DEFAULT_ENCODING = UTF_8;

    public static Reader getResourceAsReader(Class<?> contextClass, String name) throws IOException {
        return getResourceAsReader(contextClass, name, DEFAULT_ENCODING);
    }

    public static Reader getResourceAsReader(Class<?> contextClass, String name, String enc)
            throws IOException {
        InputStream in = contextClass.getResourceAsStream(name);
        if (in == null)
            throw new IOException("no such resource with name " + name);

        return new InputStreamReader(in, enc);
    }

    public static String getResourceAsString(Class<?> contextClass, String name) throws IOException {
        return getResourceAsString(contextClass, name, null);
    }

    public static String getResourceAsString(Class<?> contextClass, String name, String enc)
            throws IOException {
        InputStream in = contextClass.getResourceAsStream(name);
        if (in == null)
            throw new IOException("no such resource with name " + name);

        ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);

        copyAndClose(in, bout);

        return bout.toString(JExtn.ifNullOrBlank(enc, DEFAULT_ENCODING));

    }

    public static Reader getResourceAsReader(Class<?> contextClass, String name, String enc, boolean lenient)
            throws IOException {
        InputStream in = contextClass.getResourceAsStream(name);
        if (in == null) {
            if (lenient) {
                return null;
            }
            throw new IOException("no such resource with name " + name);
        }

        return new InputStreamReader(in, JExtn.ifNullOrBlank(enc, DEFAULT_ENCODING));
    }

    /**
     * @param url
     *            is the URL or file path
     * @return null if not able to load the reader specified by url
     */
    public static Reader getAsReader(String url) throws IOException {
        URL resource = findResource(url);
        Reader reader = null;
        if (resource != null) {
            reader = new InputStreamReader(resource.openStream(), DEFAULT_ENCODING);
        }

        JExtn.checkNull(reader, "Invalid resource url'" + url + "'");

        return reader;
    }

    public static URL findResource(String url) {
        URL resource = null;
        if (JExtn.hasValue(url)) {
            try {
                resource = new URL(url);
            } catch (MalformedURLException e) {
            }

            if (resource == null) {
                resource = Thread.currentThread().getContextClassLoader().getResource(url);
            }
        }

        return resource;
    }

    public static Properties getConfigurationByUrl(String url) {
        Properties properties = null;
        try {
            Reader reader = getAsReader(url);
            properties = new jf.jextn.util.Properties();

            properties.load(reader);

            closeQuietly(reader);
        } catch (IOException e) {
            properties = null;
        }

        return properties;
    }

    /**
     * Return the content of the reader.
     *
     * @param file
     *            the non-binary file.
     * @return the String content
     */
    public static String getContentAsString(Reader reader) {
        String content = null;
        try {
            StringWriter sw = new StringWriter(1 * 1024);

            copyAndClose(reader, sw);

            content = sw.toString();
        } catch (IOException e) {
            // error occurred
        }

        return content;
    }

    /**
     * Return the content of the file.
     *
     * @param file
     *            the non-binary file.
     * @return the String content
     */
    public static String getContentAsString(String url) {
        String content = null;
        try {
            StringWriter sw = new StringWriter(1 * 1024);
            URL resourceURL = findResource(url);
            if (resourceURL != null) {
                InputStream in = resourceURL.openStream();
                InputStreamReader reader = new InputStreamReader(in, DEFAULT_ENCODING);

                copyAndClose(reader, sw);
            }

            content = sw.toString();
        } catch (IOException e) {
            // error occurred
        }

        return content;
    }
}
